<template>
    <div class="tree-content">
        <a-input-search class="mb10" style="width: 100%" placeholder="搜索" @change="onSearchChange" allowClear />
        <a-spin :spinning="treeLoading">
            <a-tree
                :show-line="true"
                :expandedKeys="expandedTreeNodeKeys"
                :auto-expand-parent="autoExpandParent"
                :selectedKeys="currSelectedTreeNode"
                :show-icon="true"
                :load-data="onLoadTreeData"
                :tree-data="areaData"
                :replace-fields="{
                    title: 'name',
                    key: 'id',
                }"
                :loadedKeys="loadedKeys"
                @select="selectTreeItem"
                @expand="expandTreeNode"
            >
                <template slot="title" slot-scope="{ name, id }">
                    <div style="display: flex" :id="id">
                        <span class="tree-title" :title="name" v-if="name.indexOf(searchValue) > -1">
                            {{ name.substr(0, name.indexOf(searchValue)) }}
                            <span style="color: #1890ff">{{ searchValue }}</span>
                            {{ name.substr(name.indexOf(searchValue) + searchValue.length) }}
                        </span>
                        <span class="tree-title" v-else>{{ name | noDataFormat }}</span>
                    </div>
                </template>
            </a-tree>
        </a-spin>
    </div>
</template>
<script>
import { getSelectedIds, optionsIsExitId, getParentKey, generateList } from '@/utils/methods'
import { areaApi } from '../../common/api/setting'
import { mapMutations } from 'vuex'
export default {
    components: {},
    props: {
        areaData: {
            require: true,
            type: Array,
        },
        expandedTreeNodeKeys: {
            required: true,
            type: Array,
        },
        extraTitle: {
            required: false,
            type: Boolean,
            default: false,
        },
        api: {
            required: false,
            type: Function,
            default: params => {
                return areaApi.children(params)
            },
        },
        hiddenTypes: {
            required: false,
            type: Array,
            default: () => [],
        },
        disabledSelectingFunction: {
            required: false,
            type: Function,
            default: () => {
                return false
            },
        },
    },
    data() {
        this.searchTreeTimer = null
        return {
            autoExpandParent: false,
            searchValue: '',
            currSelectedTreeNode: [],
            treeLoading: false,
            searchAreaId: undefined,
            // （受控）已经加载的节点，需要配合 loadData 使用。
            // 设置为空,则每一次点击展开节点都会调用onLoadTreeData，否则之前已经展开过的节点再次点击展开可能就不会调用loadData了
            loadedKeys: [],
        }
    },
    watch: {
        api: {
            handler() {
                this.initData()
            },
            immediate: false,
        },
        hiddenTypes: {
            handler(newValue, oldValue) {
                if (JSON.stringify(newValue) === JSON.stringify(oldValue)) return
                this.initData()
            },
            immediate: false,
        },
        areaData(areaData) {
            console.log(areaData)
            this.$store.state.treeData = areaData
        },
        areaTreeSelectedId(areaTreeSelectedId) {
            this.currSelectedTreeNode = areaTreeSelectedId
        },
    },
    computed: {
        areaTreeSelectedId() {
            return this.$store.state.areaTreeSelectedId
        },
    },
    mounted() {
        this.initData()
    },
    methods: {
        initData() {
            let id = this.$store.state.userInfo.areaId
            this.getTreeNodes({ id })
        },
        ...mapMutations(['setAreaTreeSelectedId']),
        scrollIntoView(value) {
            setTimeout(() => {
                const el = document.getElementById(value)
                console.log(el, 'el')
                el && el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'start' })
            }, 600)
        },
        onSearchChange(e) {
            clearTimeout(this.searchTreeTimer)
            this.searchTreeTimer = setTimeout(() => {
                const value = e.target.value
                this.searchValue = value
                if (value) {
                    const expandedKeys = generateList(this.areaData)
                        .map(item => {
                            if (item.title.indexOf(value) > -1) {
                                console.log(item)
                                const parentKey = getParentKey(this.areaData, item.key)
                                return parentKey
                            }
                            return null
                        })
                        .filter((item, i, self) => item && self.indexOf(item) === i)
                    const rootKeys = this.areaData.filter(({ name }) => name.includes(value)).map(({ id }) => id)
                    this.autoExpandParent = true
                    expandedKeys.concat(rootKeys).length &&
                        this.scrollIntoView(Array.from(new Set([...rootKeys, ...expandedKeys]))[0])
                    expandedKeys.length && this.$emit('update:expandedTreeNodeKeys', expandedKeys)
                    return
                }
            }, 500)
        },
        expandTreeNode(expandedTreeNodeKeys) {
            console.log(expandedTreeNodeKeys, 'expandedTreeNodeKeys--tree')
            this.autoExpandParent = false
            this.$emit('update:expandedTreeNodeKeys', expandedTreeNodeKeys)
        },
        // 点击树节点
        selectTreeItem(selectedKeys, info) {
            const { selectedNodes } = info
            if (selectedKeys.length > 0) {
                const { type } = selectedNodes[0].data.props
                if (this.disabledSelectingFunction(type)) {
                    this.$emit('selectTreeItem', selectedKeys)
                    return
                }
                this.currSelectedTreeNode = selectedKeys
                this.setAreaTreeSelectedId(selectedKeys)
                this.$emit('selectTreeItem', this.currSelectedTreeNode)
            }
        },
        // 懒加载
        onLoadTreeData(treeNode) {
            // expandedTreeNodeKeys更新,treeData找不到对应展开key数据会触发此方法,并且会依次触发展开
            console.log('onLoadTreeData')
            return new Promise((resolve, reject) => {
                const currNode = treeNode.dataRef
                console.log(currNode, 'currNode')
                if (treeNode.dataRef.children) {
                    resolve()
                    return
                }
                console.log(treeNode, 'treeNode')
                // 浅拷贝
                this.getTreeNodes(currNode)
                    .then(() => {
                        resolve()
                    })
                    .catch(() => {
                        // 报错则收起当前展开节点
                        const currExpandNodeIdIndex = this.expandedTreeNodeKeys.indexOf(currNode.id)
                        if (currExpandNodeIdIndex > -1) {
                            this.expandedTreeNodeKeys.splice(currExpandNodeIdIndex, 1)
                        }
                        resolve() // 必须resolve
                        // currNode.loading = false;
                        // reject(new Error());
                    })
            })
        },
        async getTreeNodes(currNode = {}) {
            console.log('===========getTreeNodes==============')
            if (!currNode.id) {
                this.treeLoading = true
            }
            await this.api({ id: currNode.id }).then(res => {
                if (res.code == 200) {
                    let areaArr = [res.data]
                    if (this.areaData.length === 0) {
                        this.treeLoading = false
                        this.$emit('update:areaData', [...areaArr])
                        let areaTreeSelectedId = this.$store.state.areaTreeSelectedId
                        // 树数据找不到areaTreeSelectedId， 则重置areaTreeSelectedId
                        if (
                            areaTreeSelectedId &&
                            areaTreeSelectedId.length &&
                            !optionsIsExitId(areaArr, areaTreeSelectedId[0])
                        ) {
                            areaTreeSelectedId = []
                        }
                        // 赋初值
                        if (!areaTreeSelectedId || !areaTreeSelectedId.length) {
                            areaTreeSelectedId = areaArr.length ? [areaArr[0].id] : []
                            if (areaArr[0].children?.length > 0) {
                                areaTreeSelectedId = [areaArr[0].children[0].id]
                            }
                            this.setAreaTreeSelectedId(areaTreeSelectedId)
                        }
                        // 展开到选中节点
                        this.$emit('update:expandedTreeNodeKeys', getSelectedIds(areaArr, areaTreeSelectedId[0]))
                        // 滚动到选中位置
                        this.scrollIntoView(areaTreeSelectedId[0])
                        this.currSelectedTreeNode = areaTreeSelectedId || []
                        this.$emit('selectTreeItem', this.currSelectedTreeNode)
                        return
                    }
                    currNode.children = [...res.data.children]
                    this.$emit('update:areaData', [...this.areaData])
                }
            })
        },
    },
}
</script>
<style lang="scss" scoped>
/deep/.ant-spin-nested-loading > div > .ant-spin {
    height: 400px;
}
/deep/ .ant-tree {
    min-height: calc(100vh - 248px);
    max-height: calc(100vh - 248px);
    overflow-y: auto;
}
</style>
